use anyhow::Result;
use std::sync::Arc;
use sqlx::SqlitePool;

use crate::database::models::CreateUserRequest;
use crate::database::repository::{UserRepository, SqliteUserRepository};
use crate::auth::user::PasswordManager;
use shared::types::User;

#[derive(Clone)]
pub struct UserService {
    user_repo: Arc<dyn UserRepository>,
}

impl UserService {
    pub fn new(pool: SqlitePool) -> Self {
        Self {
            user_repo: Arc::new(SqliteUserRepository::new(pool)),
        }
    }
    
    /// 创建新用户
    pub async fn create_user(&self, request: &CreateUserRequest) -> Result<User> {
        // 验证用户名唯一性
        if self.user_repo.get_user_by_username(&request.username).await?.is_some() {
            return Err(anyhow::anyhow!("Username already exists"));
        }
        
        // 验证用户名格式
        self.validate_username(&request.username)?;
        
        // 验证密码强度
        self.validate_password(&request.password)?;
        
        // 哈希密码
        let (password_hash, salt) = PasswordManager::hash_password(&request.password)?;
        
        // 创建用户（使用哈希后的密码）
        let user = self.user_repo.create_user_with_hash(
            &request.username,
            &password_hash,
            &salt,
            &request.home_directory,
            request.max_storage_size.unwrap_or(1073741824)
        ).await?;
        
        Ok(user)
    }
    
    /// 验证用户登录
    pub async fn authenticate_user(&self, username: &str, password: &str) -> Result<User> {
        let user = self.user_repo.get_user_by_username(username).await?
            .ok_or_else(|| anyhow::anyhow!("Invalid username or password"))?;
        
        if !user.is_active {
            return Err(anyhow::anyhow!("Account is disabled"));
        }
        
        // 验证密码
        if !PasswordManager::verify_password(password, &user.password_hash, &user.salt)? {
            return Err(anyhow::anyhow!("Invalid username or password"));
        }
        
        // 更新登录信息
        let mut updated_user = user.clone();
        updated_user.last_login = Some(chrono::Utc::now());
        updated_user.login_count += 1;
        
        self.user_repo.update_user(&updated_user).await?;
        
        Ok(updated_user)
    }
    
    /// 根据ID获取用户
    pub async fn get_user_by_id(&self, id: i64) -> Result<Option<User>> {
        self.user_repo.get_user_by_id(id).await
    }
    
    /// 根据用户名获取用户
    pub async fn get_user_by_username(&self, username: &str) -> Result<Option<User>> {
        self.user_repo.get_user_by_username(username).await
    }
    
    /// 更新用户信息
    pub async fn update_user(&self, user: &User) -> Result<()> {
        self.user_repo.update_user(user).await
    }
    
    /// 删除用户
    pub async fn delete_user(&self, id: i64) -> Result<()> {
        self.user_repo.delete_user(id).await
    }
    
    /// 列出用户
    pub async fn list_users(&self, limit: i64, offset: i64) -> Result<Vec<User>> {
        self.user_repo.list_users(limit, offset).await
    }
    
    /// 验证用户名格式
    fn validate_username(&self, username: &str) -> Result<()> {
        if username.is_empty() || username.len() > 50 {
            return Err(anyhow::anyhow!("Username must be 1-50 characters long"));
        }
        
        if !username.chars().all(|c| c.is_alphanumeric() || c == '_' || c == '-') {
            return Err(anyhow::anyhow!("Username can only contain letters, numbers, underscore and dash"));
        }
        
        Ok(())
    }
    
    /// 验证密码强度
    fn validate_password(&self, password: &str) -> Result<()> {
        if password.len() < 6 {
            return Err(anyhow::anyhow!("Password must be at least 6 characters long"));
        }
        
        if password.len() > 128 {
            return Err(anyhow::anyhow!("Password must be no more than 128 characters long"));
        }
        
        Ok(())
    }
}
